package org.chronologger.poppaea.client.widgets;

import org.chronologger.poppaea.client.domain.Location;
import org.chronologger.poppaea.client.i18n.LocationWidgetConsts;
import org.chronologger.poppaea.client.utils.Pair;
import org.chronologger.poppaea.client.utils.Pair.StringWidgetPair;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBox;

public class LocationEditor extends ArrowPopupPanel {
	
	private static final int EDITOR_ARROW_X_OFFSET = 5;
	private static final int EDITOR_ARROW_Y_OFFSET = 15;
	private static final int EDITOR_CONTENT_HEIGHT = 120;
	private static final int EDITOR_CONTENT_WIDTH = 320;

	private static LocationEditor instance = null;
	
	private static final LocationWidgetConsts lang = GWT
	.create(LocationWidgetConsts.class);
	 
	private final FlexTable table = new FlexTable();
	private final TextBox titleBox = new TextBox();
	private final SegmentedButton submitButton = new SegmentedButton();
	private final SegmentedButton colorButton = new SegmentedButton();
	private final SegmentedButton deleteButton = new SegmentedButton();
	
	private final Pair.StringWidgetPair rows[] = new Pair.StringWidgetPair[] {
			new Pair.StringWidgetPair(lang.title(), titleBox),
			new Pair.StringWidgetPair(lang.color(), colorButton),
			new Pair.StringWidgetPair("", submitButton),
			new Pair.StringWidgetPair(lang.delete(), deleteButton)};

	private Location location;
	private LocationWidget widget;
	
	private LocationEditor() {
		
		// Handlers - refractor?
		this.getContentPanel().addEventHandler(Event.ONDBLCLICK, EventHandler.doNothing);
		
		KeyDownHandler cancelActionHandler = new KeyDownHandler() {

			public void onKeyDown(KeyDownEvent event) {
				switch (event.getNativeKeyCode()) {
				case KeyCodes.KEY_ESCAPE:
					cancel();
					break;
				}
			}
		};

		KeyDownHandler saveActionHandler = new KeyDownHandler() {

			public void onKeyDown(KeyDownEvent event) {
				switch (event.getNativeKeyCode()) {
				case KeyCodes.KEY_ENTER:
					save();
					event.stopPropagation();
					event.preventDefault();
					break;
				}
			}
		};
		
		// buttons
		colorButton.addSegment("").addClickHandler(ColorPicker.createClickHandler(colorButton));
		colorButton.setHoverColor("");
		colorButton.setSegmentSize(0, 16, 16);
		
		submitButton.setColor("grey");
		submitButton.addSegment(lang.done()).addClickHandler(
				new ClickHandler() {
					public void onClick(ClickEvent event) {
						try {
							hide(true);
						} catch(Exception e) {
							// fail
						}
					}
				});
		submitButton.getSegment(0).getElement().getStyle().setProperty(
				"fontSize", "1.1em");
		
		deleteButton.setColor("red");
		deleteButton.addSegment(lang.delete());
		
		table.setWidth("100%");
		table.addStyleName("property-list");
		table.getColumnFormatter().setWidth(0, "100px");
		
		FocusWidget lastFocusWidget = null;
		for (Pair.StringWidgetPair p : rows) {
			table.setText(table.getRowCount(), 0, p.a);
			table.setWidget(table.getRowCount() - 1, 1, p.b);

			table.getCellFormatter().addStyleName(table.getRowCount() - 1, 0,
					"property-list-name");
			if (p.b instanceof FocusWidget && !(p.b instanceof Button)) {
				lastFocusWidget = (FocusWidget) p.b;
				if (lastFocusWidget instanceof TextBox) {
					lastFocusWidget.addKeyDownHandler(saveActionHandler);
				}
				lastFocusWidget.addKeyDownHandler(cancelActionHandler);
			}
		}
		
		addCloseHandler(new CloseHandler<PopupPanel>() {

			public void onClose(CloseEvent<PopupPanel> event) {
				if (event.isAutoClosed())
					save();
			}
		});

		getContentPanel().add(table);

		lastFocusWidget.addKeyDownHandler(new KeyDownHandler() {

			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_TAB) {
					titleBox.setFocus(true);
					event.preventDefault();
					event.stopPropagation();
				}
			}
		});
	}
	
	public static LocationEditor getInstance() {
		if (instance == null)
			instance = new LocationEditor();
		return instance;
	}

	public void cancel() {
		location = null;
		hide();
	}

	public void save() {
		updateLocation();
		location = null;
		hide();
	}
	
	public void setLocation(Location location) {
		if (this.location != location) {
			if (this.widget != null) 
				this.removeAutoHidePartner(widget.getElement());
			this.location = location;
			this.widget = location.getWidget();			
			addAutoHidePartner(widget.getElement());
			
			titleBox.setText(location.getName());			
			colorButton.setColor(location.getColor());
			for(StringWidgetPair r : rows) {
				if(r.b instanceof SegmentedButton)
					((SegmentedButton)r.b).resetHoverState();
			}
			
			pointAt(widget.getAbsoluteLeft() + EDITOR_ARROW_X_OFFSET, widget
					.getAbsoluteLeft()
					+ widget.getOffsetWidth() - EDITOR_ARROW_X_OFFSET, widget
					.getAbsoluteTop()
					+ EDITOR_ARROW_Y_OFFSET, EDITOR_CONTENT_WIDTH,
					EDITOR_CONTENT_HEIGHT);
			titleBox.setFocus(true);
		}
	}

	private void updateLocation() {
		String newTitle = titleBox.getText().trim();
		if (newTitle != "") {
			location.setName(newTitle);
		}
		location.setColor(colorButton.getColor());
	}

}